#include "segment.h"

#include <stdio.h>
#include <assert.h>

#include "util/log.h"
#include "util/mt.h"

#include "rooms/boss.h"
#include "rooms/corridor.h"
#include "rooms/goal.h"
#include "rooms/monsters.h"
#include "rooms/sokoban.h"
#include "rooms/spawn.h"
#include "rooms/switches.h"

static void LAYOUT_GENERATOR_MISSING (Segment* segment, Layout* layout, Generator* generator)
{
	#if TOWERHACK_DEBUG
	log_fatal ("Fail! No layout generator for segment type %s.", segment->type->name);
	#endif
	assert(!"Fail! Segment type has no layout generator.");
}

static void ROOMCONTENT_GENERATOR_MISSING (Segment* segment, Layout* layout, Map* map,
                                           Coord* entrance, int n_entrances,
                                           Coord* exit, int n_exits)
{
	#if TOWERHACK_DEBUG
	log_fatal ("Fail! No room content generator for segment type %s.", segment->type->name);
	#endif
	assert(!"Fail! Segment type has no room content generator.");
}

SegmentType SEGTYPE [11] = {
	{ ST_SPAWN,       "SPAWN",       0, 0,         1, 1,            1, 1, &room_spawn_layout, &room_spawn_content },
	{ ST_CORRIDOR,    "CORRIDOR",    1, MAX_ROOTS, 1, MAX_BRANCHES, 1, 1, &room_corridor_layout, &room_corridor_content },
	{ ST_MULTIPLEXER, "MULTIPLEXER", 1, MAX_ROOTS, 1, MAX_BRANCHES, 1, 1, &LAYOUT_GENERATOR_MISSING, &ROOMCONTENT_GENERATOR_MISSING },
	{ ST_SHORTCUT,    "SHORTCUT",    2, 2,         2, 2,            2, 2, &LAYOUT_GENERATOR_MISSING, &ROOMCONTENT_GENERATOR_MISSING },
	{ ST_TREASURE,    "TREASURE",    1, MAX_ROOTS, 1, MAX_BRANCHES, 1, 1, &LAYOUT_GENERATOR_MISSING, &ROOMCONTENT_GENERATOR_MISSING },
	{ ST_MONSTERS,    "MONSTERS",    1, MAX_ROOTS, 1, MAX_BRANCHES, 1, 1, &room_monsters_layout, &room_monsters_content },
	{ ST_BOSS,        "BOSS",        1, 1,         1, 1,            1, 1, &room_boss_layout, &room_boss_content },
	{ ST_SWITCHES,    "SWITCHES",    1, 1,         1, 1,            1, 1, &room_switches_layout, &room_switches_content },
	{ ST_SOKOBAN,     "SOKOBAN",     1, 1,         1, 1,            1, 1, &room_sokoban_layout, &room_sokoban_content },
	{ ST_MULTIPLAYER, "MULTIPLAYER", 2, MAX_ROOTS, 2, 2,            1, 1, &LAYOUT_GENERATOR_MISSING, &ROOMCONTENT_GENERATOR_MISSING },
	{ ST_GOAL,        "GOAL",        1, MAX_ROOTS, 0, 0,            1, 1, &room_goal_layout, &room_goal_content }
};

void segment_generate (Segment* s, SegmentTypeId t, int intensity)
{
	s->type = &SEGTYPE[t];
	s->intensity = intensity;
	s->n_roots = mt_randint(s->type->min_roots, s->type->max_roots+1);
	s->n_branches = mt_randint(s->type->min_branches, s->type->max_branches+1);
	s->n_rooms = mt_randint(s->type->min_rooms, s->type->max_rooms+1);
}

void segment_make_support_corridor (Segment* s, int n_roots, int n_branches)
{
	s->type = &SEGTYPE[ST_CORRIDOR];
	s->intensity = 0;
	s->n_roots = n_roots;
	s->n_branches = n_branches;
	s->n_rooms = 1;
}

void segment_make_goal (Segment* s, int n_roots)
{
	s->type = &SEGTYPE[ST_GOAL];
	s->intensity = 0;
	s->n_roots = n_roots;
	s->n_branches = 0;
	s->n_rooms = 1;
}

void segment_plant_obstacles (Map* map, Coord* coord, int n_coords)
{
	for (int i = 0; i < n_coords; i++) {
		MapObject* obstacle = map_add_object (map, coord[i]);
		map_object_make_obstacle (obstacle);
	}
}
